﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using KickStart.Models;
using KickStart.Services;

namespace KickStart.Helpers
{
    public class AuthorizeWithTokenAttribute : AuthorizeAttribute
    {
        public IMembershipService MembershipService { get; private set; }

        public AuthorizeWithTokenAttribute()
            : this(null)
        {
        }

        public AuthorizeWithTokenAttribute(IMembershipService service)
        {
            MembershipService = service ?? new AccountMembershipService();
        }

        protected override bool AuthorizeCore(HttpContextBase httpContext)
        {
            var username = httpContext.Request.Form["username"] ??
                           httpContext.Request["username"];
            var password = httpContext.Request.Form["password"] ??
                           httpContext.Request["password"];
            return ValidateSignIn(username, password) || httpContext.User.Identity.IsAuthenticated;
        }

        public override void OnAuthorization(AuthorizationContext filterContext)
        {
            var httpContext = filterContext.HttpContext;
            var username = httpContext.Request.Form["username"] ??
                           httpContext.Request["username"];
            var password = httpContext.Request.Form["password"] ??
                           httpContext.Request["password"];
            if (!AuthorizeCore(filterContext.HttpContext))
            {
                var data = new ApiResponse
                               {
                                   success = false,
                                   errors = GetErrors(username, password)
                               };

                filterContext.Result = JsonPoxAttribute.GetResult(filterContext.HttpContext, data);
                if (filterContext.Result == null)
                {
                    filterContext.Result = new HttpUnauthorizedResult();
                }
            }
        }

        private List<JsonError> GetErrors(string userName, string password)
        {
            var modelState = new ModelStateDictionary();
            if (String.IsNullOrEmpty(userName))
            {
                modelState.AddModelError("username", "You must specify a username.");
            }
            if (String.IsNullOrEmpty(password))
            {
                modelState.AddModelError("password", "You must specify a password.");
            }
            if (!MembershipService.ValidateUser(userName, password))
            {
                modelState.AddModelError("_FORM", "The username or password provided is incorrect.");
            }

            return modelState.ToJson();
        }

        private bool ValidateSignIn(string userName, string password)
        {
            if (String.IsNullOrEmpty(userName))
            {
                return false;
            }
            if (String.IsNullOrEmpty(password))
            {
                return false;
            }
            if (!MembershipService.ValidateUser(userName, password))
            {
                return false;
            }

            return true;
        }
    }
}